/**
 * API client with JWT authentication support
 */

interface ApiResponse<T = any> {
  status: boolean;
  message: string;
  data?: T;
  detail?: string;
}

class ApiClient {
  private baseUrl: string;

  constructor(baseUrl: string = '/api') {
    this.baseUrl = baseUrl;
  }

  private getAuthHeaders(): Record<string, string> {
    const token = localStorage.getItem('access_token');
    const headers: Record<string, string> = {
      'Content-Type': 'application/json',
    };

    if (token) {
      headers['Authorization'] = `Bearer ${token}`;
    }

    return headers;
  }

  private async handleResponse<T>(response: Response): Promise<ApiResponse<T>> {
    const contentType = response.headers.get('content-type');
    
    if (contentType && contentType.includes('application/json')) {
      const data = await response.json();
      
      if (!response.ok) {
        // Handle 401 Unauthorized - token expired or invalid
        if (response.status === 401) {
          localStorage.removeItem('access_token');
          localStorage.removeItem('token_type');
          window.location.reload(); // Force re-authentication
        }
        
        throw new Error(data.detail || data.message || `HTTP ${response.status}`);
      }
      
      return data;
    } else {
      if (!response.ok) {
        throw new Error(`HTTP ${response.status}: ${response.statusText}`);
      }
      
      return {
        status: true,
        message: 'Success',
        data: null as T,
      };
    }
  }

  async get<T>(endpoint: string): Promise<ApiResponse<T>> {
    const response = await fetch(`${this.baseUrl}${endpoint}`, {
      method: 'GET',
      headers: this.getAuthHeaders(),
    });

    return this.handleResponse<T>(response);
  }

  async post<T>(endpoint: string, data?: any): Promise<ApiResponse<T>> {
    const response = await fetch(`${this.baseUrl}${endpoint}`, {
      method: 'POST',
      headers: this.getAuthHeaders(),
      body: data ? JSON.stringify(data) : undefined,
    });

    return this.handleResponse<T>(response);
  }

  async put<T>(endpoint: string, data?: any): Promise<ApiResponse<T>> {
    const response = await fetch(`${this.baseUrl}${endpoint}`, {
      method: 'PUT',
      headers: this.getAuthHeaders(),
      body: data ? JSON.stringify(data) : undefined,
    });

    return this.handleResponse<T>(response);
  }

  async delete<T>(endpoint: string): Promise<ApiResponse<T>> {
    const response = await fetch(`${this.baseUrl}${endpoint}`, {
      method: 'DELETE',
      headers: this.getAuthHeaders(),
    });

    return this.handleResponse<T>(response);
  }

  // Auth-specific methods
  async login(username: string, password: string) {
    return this.post('/auth/login', { username, password });
  }

  async register(userData: {
    username: string;
    password: string;
    email?: string;
    full_name?: string;
  }) {
    return this.post('/auth/register', userData);
  }

  async getCurrentUser() {
    return this.get('/auth/me');
  }

  // Session methods
  async getSessions() {
    return this.get('/sessions');
  }

  async createSession(data: any) {
    return this.post('/sessions', data);
  }

  async updateSession(sessionId: string, data: any) {
    return this.put(`/sessions/${sessionId}`, data);
  }

  async deleteSession(sessionId: string) {
    return this.delete(`/sessions/${sessionId}`);
  }

  // Plans methods
  async getPlans(userId?: string) {
    const params = userId ? `?user_id=${userId}` : '';
    return this.get(`/plans${params}`);
  }

  async createPlan(data: any) {
    return this.post('/plans', data);
  }

  // Teams methods
  async getTeams(userId?: string) {
    const params = userId ? `?user_id=${userId}` : '';
    return this.get(`/teams${params}`);
  }

  async createTeam(data: any) {
    return this.post('/teams', data);
  }

  // Settings methods
  async getSettings(userId?: string) {
    const params = userId ? `?user_id=${userId}` : '';
    return this.get(`/settings${params}`);
  }

  async updateSettings(data: any) {
    return this.put('/settings', data);
  }
}

// Create and export a singleton instance
export const apiClient = new ApiClient();

// Helper function for handling API calls with error handling
export async function handleApiCall<T>(
  apiCall: () => Promise<ApiResponse<T>>,
  errorMessage: string = 'An error occurred'
): Promise<T | null> {
  try {
    const response = await apiCall();
    if (response.status) {
      return response.data || null;
    } else {
      console.error(errorMessage, response.message);
      return null;
    }
  } catch (error) {
    console.error(errorMessage, error);
    return null;
  }
}

export default apiClient;